(*{{{ Window Params *)
value win_width = ref 800;
value win_height = ref 800;
value win_title = ("[SDL based]","HellHole");
value scroll_offset = ref (0,0);

value myinit () =
  let light_ambient = (1.0, 1.0, 1.0, 1.0)
  and light_diffuse = (1.0, 1.0, 1.0, 0.5)
  and light_specular = (1.0, 1.0, 1.0, 1.0)
  and light_position = (1.0, 1.0, 1.0, 0.0)
  in
  (
    GlLight.light ~num:0 (`ambient light_ambient);
    GlLight.light ~num:0 (`diffuse light_diffuse);
    GlLight.light ~num:0 (`specular light_specular);
    GlLight.light ~num:0 (`position light_position);
    
    GlFunc.depth_func `less;
    List.iter Gl.enable [`lighting; `light0; `depth_test]
  );

value initScreen () =
  (

(*     Sdlgl.set_attr [ (*Sdlgl.DEPTH_SIZE 16*) Sdlgl.DOUBLEBUFFER True]; *)

    ignore(Sdlvideo.set_video_mode win_width.val win_height.val [`OPENGL]);
    (
      myinit ();
      Sdlwm.set_caption (fst win_title) (snd win_title);      
      Printf.printf  "DRIVER: %s\n" (Sdlvideo.driver_name ());
      let test v = if v then "ЕСТЬ" else "НЕТ" in
      let vi = Sdlvideo.get_video_info () in
      (
        print_endline ("Аппаратная поддержка сурфейсов:      [" ^ (test vi.Sdlvideo.hw_available) ^ "]" );
        print_endline ("Менеджер окон:                       [" ^ (test vi.Sdlvideo.wm_available) ^ "]" );
        print_endline ("Ускоренная отрисовка HW -> HW:       [" ^ (test vi.Sdlvideo.blit_hw) ^ "]" );
        print_endline ("Ускоренная отрисовка HW с color_key: [" ^ (test vi.Sdlvideo.blit_hw_color_key) ^ "]" );
        print_endline ("Ускоренная отрисовка HW с альфой:    [" ^ (test vi.Sdlvideo.blit_hw_alpha) ^ "]" );
        print_endline ("Ускоренная отрисовка SW -> HW:       [" ^ (test vi.Sdlvideo.blit_sw) ^ "]" );
        print_endline ("Ускоренная отрисовка SW с color_key: [" ^ (test vi.Sdlvideo.blit_sw_color_key) ^ "]" );
        print_endline ("Ускоренная отрисовка SW с альфой:    [" ^ (test vi.Sdlvideo.blit_sw_alpha) ^ "]" );
        print_endline ("Ускоренная залика цветом:            [" ^ (test vi.Sdlvideo.blit_fill) ^ "]" );
        print_endline ("Доступно видео памяти:               [" ^ (string_of_int vi.Sdlvideo.video_mem) ^ "]" );
      );

      GlClear.color (44.0 /. 255.0 , 84.0 /. 255.0, 47.0 /. 255.0) ~alpha:1.0;
      Gl.enable `depth_test; 
      GlFunc.depth_func `lequal;
      (* устанавливаем вьюпорт в размерах нашего экрана *)
      GlDraw.viewport ~x:(fst scroll_offset.val) ~y:(snd scroll_offset.val) ~w:win_width.val ~h:win_height.val;

(*        Устанавливаем ортогональное проецирование *)
(*      GlMat.mode `projection; 
      GlMat.load_identity (); *)

(*      GlMat.ortho 
        ~x:(0.0,float_of_int win_width.val)
        ~y:(float_of_int win_height.val,0.0)
        ~z:(1., 1.);*)
      GlMat.ortho ~x: (0.0, 0.0) ~y: (0.0, 0.0) 
                ~z: (-100.0, 0.0);
      (* возвращаемся к модельвью из проекции *)
      GlMat.mode `modelview;
      GlMat.load_identity ();
    );
  );
(*}}}*)


open Gl;
value pi = acos (-1.);
value cube () =
  let quads f (color1,color2) =
    let rgba (r,g,b) = (r,g,b,1.0) in
    (
      GlMat.push();
        GlDraw.color color1;
        f ();
        GlDraw.begins `quads;
          GlLight.material `both (`ambient_and_diffuse (rgba color1));
          GlDraw.normal3 (1.,1.,-1.);
          GlDraw.vertex ~x:(-0.5) ~y:(-0.5) ~z:(-0.5)();
          GlDraw.vertex ~x:(-0.5) ~y:(0.5) ~z:(-0.5)();
          GlDraw.vertex ~x:(0.5) ~y:(0.5) ~z:(-0.5)();
          GlDraw.vertex ~x:(0.5) ~y:(-0.5) ~z:(-0.5)();
        GlDraw.ends ();
        GlDraw.color color2;
        GlDraw.begins `quads;
          GlLight.material `both (`ambient_and_diffuse (rgba color2));
          GlDraw.normal3 (1.,1.,1.);
          GlDraw.vertex ~x:(-0.5) ~y:(-0.5) ~z:(0.5)();
          GlDraw.vertex ~x:(-0.5) ~y:(0.5) ~z:(0.5)();
          GlDraw.vertex ~x:(0.5) ~y:(0.5) ~z:(0.5)();
          GlDraw.vertex ~x:(0.5) ~y:(-0.5) ~z:(0.5)();
        GlDraw.ends ();
      GlMat.pop();
    )
  in
  (
    quads begin fun () -> 
      ()
    end ((1.0,0.0,0.0),(0.0,1.0,0.0));
    quads begin fun () ->
      GlMat.rotate ~angle:90.0 ~x:1.0 ();
    end ((0.0,0.0,1.0),(1.0,1.0,0.0));
    quads begin fun () ->
      GlMat.rotate ~angle:90.0 ~y:1.0 ();
    end ((1.0,0.0,1.0),(0.0,1.0,1.0));
  );
  


value render () = 
  (
    GlClear.color (0.0, 0.0, 0.0);
    GlClear.clear [`color; `depth];
    GlDraw.color (1.0, 1.0, 1.0);
    GlMat.mode `projection;
    GlMat.rotate ~angle:5.0 ~y:1.0 ~x:0.0 ~z:0.0 ();
    cube ();
    Gl.flush(); 
    Sdlgl.swap_buffers ();
  );
value ui_events_handler _ = (* {{{ *)
  (
   while Sdlevent.has_event () do
    match Sdlevent.poll () with
    [ None -> ()
    | Some e ->
      match e with
      [ Sdlevent.QUIT -> exit 0          
      | event -> ()
      ]       
    ]
   done;
(*    Unix.sleep 1; *)
    Unix.select [] [] [] 0.1;
   render ();
  ); (* }}} *)

value _ = 
  (
    initScreen ();
    while (True) do ui_events_handler () done;
  );

